package com.zenithmind.chat.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.chat.mapper.ChatGroupSettingMapper;
import com.zenithmind.chat.pojo.entity.ChatGroupSetting;
import com.zenithmind.chat.pojo.dto.ChatGroupSettingDTO;
import com.zenithmind.chat.pojo.vo.ChatGroupSettingVO;
import com.zenithmind.chat.service.ChatGroupSettingService;
import com.zenithmind.common.exception.BusinessException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 群组设置服务实现类 - 遵循单一职责原则
 * 只负责群组设置的业务逻辑处理
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ChatGroupSettingServiceImpl extends ServiceImpl<ChatGroupSettingMapper, ChatGroupSetting> 
        implements ChatGroupSettingService {

    @Override
    public ChatGroupSettingVO getGroupSetting(String groupId) {
        if (groupId == null || groupId.trim().isEmpty()) {
            throw new BusinessException("群组ID不能为空");
        }
        
        LambdaQueryWrapper<ChatGroupSetting> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatGroupSetting::getGroupId, groupId)
                   .eq(ChatGroupSetting::getIsDeleted, 0);
        
        ChatGroupSetting setting = getOne(queryWrapper);
        if (setting == null) {
            // 如果没有设置，创建默认设置
            setting = createDefaultSettingEntity(groupId, "system");
            save(setting);
        }
        
        return convertToVO(setting);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateGroupSetting(ChatGroupSettingDTO dto, String operatorId) {
        if (!dto.isValid()) {
            throw new BusinessException("群组设置信息不完整");
        }
        
        LambdaQueryWrapper<ChatGroupSetting> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatGroupSetting::getGroupId, dto.getGroupId())
                   .eq(ChatGroupSetting::getIsDeleted, 0);
        
        ChatGroupSetting setting = getOne(queryWrapper);
        if (setting == null) {
            throw new BusinessException("群组设置不存在");
        }
        
        // 更新设置信息
        updateSettingFromDTO(setting, dto);
        setting.setUpdateTime(LocalDateTime.now());
        
        boolean result = updateById(setting);
        
        if (result) {
            log.info("更新群组设置成功，群组ID: {}, 操作人: {}", dto.getGroupId(), operatorId);
        }
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createDefaultSetting(String groupId, String creatorId) {
        if (groupId == null || groupId.trim().isEmpty()) {
            throw new BusinessException("群组ID不能为空");
        }
        
        // 检查是否已存在设置
        LambdaQueryWrapper<ChatGroupSetting> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatGroupSetting::getGroupId, groupId)
                   .eq(ChatGroupSetting::getIsDeleted, 0);
        
        if (getOne(queryWrapper) != null) {
            throw new BusinessException("群组设置已存在");
        }
        
        ChatGroupSetting setting = createDefaultSettingEntity(groupId, creatorId);
        save(setting);
        
        log.info("创建默认群组设置成功，群组ID: {}, 创建者: {}", groupId, creatorId);
        
        return setting.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteGroupSetting(String groupId, String operatorId) {
        if (groupId == null || groupId.trim().isEmpty()) {
            throw new BusinessException("群组ID不能为空");
        }
        
        LambdaQueryWrapper<ChatGroupSetting> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatGroupSetting::getGroupId, groupId)
                   .eq(ChatGroupSetting::getIsDeleted, 0);
        
        ChatGroupSetting setting = getOne(queryWrapper);
        if (setting == null) {
            throw new BusinessException("群组设置不存在");
        }
        
        // 逻辑删除
        setting.setIsDeleted(1);
        setting.setUpdateTime(LocalDateTime.now());
        
        boolean result = updateById(setting);
        
        if (result) {
            log.info("删除群组设置成功，群组ID: {}, 操作人: {}", groupId, operatorId);
        }
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateGroupName(String groupId, String groupName, String operatorId) {
        return updateSingleField(groupId, "groupName", groupName, operatorId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateGroupDescription(String groupId, String description, String operatorId) {
        return updateSingleField(groupId, "description", description, operatorId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateGroupAvatar(String groupId, String avatar, String operatorId) {
        return updateSingleField(groupId, "avatar", avatar, operatorId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateGroupNotice(String groupId, String notice, String operatorId) {
        return updateSingleField(groupId, "notice", notice, operatorId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateJoinVerification(String groupId, Boolean joinVerification, String operatorId) {
        return updateSingleField(groupId, "joinVerification", joinVerification, operatorId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateAllMuted(String groupId, Boolean allMuted, String operatorId) {
        return updateSingleField(groupId, "allMuted", allMuted, operatorId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateGroupVisibility(String groupId, Boolean isPublic, String operatorId) {
        return updateSingleField(groupId, "isPublic", isPublic, operatorId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateMemberInvitePermission(String groupId, Boolean allowMemberInvite, String operatorId) {
        return updateSingleField(groupId, "allowMemberInvite", allowMemberInvite, operatorId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateMaxMembers(String groupId, Integer maxMembers, String operatorId) {
        return updateSingleField(groupId, "maxMembers", maxMembers, operatorId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateMessageRetentionDays(String groupId, Integer messageRetentionDays, String operatorId) {
        return updateSingleField(groupId, "messageRetentionDays", messageRetentionDays, operatorId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchUpdateGroupSettings(List<String> groupIds, ChatGroupSettingDTO dto, String operatorId) {
        if (groupIds == null || groupIds.isEmpty()) {
            throw new BusinessException("群组ID列表不能为空");
        }
        
        for (String groupId : groupIds) {
            dto.setGroupId(groupId);
            updateGroupSetting(dto, operatorId);
        }
        
        log.info("批量更新群组设置成功，群组数量: {}, 操作人: {}", groupIds.size(), operatorId);
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean resetToDefault(String groupId, String operatorId) {
        if (groupId == null || groupId.trim().isEmpty()) {
            throw new BusinessException("群组ID不能为空");
        }
        
        // 删除现有设置
        deleteGroupSetting(groupId, operatorId);
        
        // 创建默认设置
        createDefaultSetting(groupId, operatorId);
        
        log.info("重置群组设置为默认值成功，群组ID: {}, 操作人: {}", groupId, operatorId);
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean copyGroupSettings(String sourceGroupId, String targetGroupId, String operatorId) {
        ChatGroupSettingVO sourceSetting = getGroupSetting(sourceGroupId);
        if (sourceSetting == null) {
            throw new BusinessException("源群组设置不存在");
        }
        
        // 创建DTO并复制设置
        ChatGroupSettingDTO dto = new ChatGroupSettingDTO();
        dto.setGroupId(targetGroupId);
        copySettingsToDTO(sourceSetting, dto);
        
        // 删除目标群组现有设置（如果存在）
        try {
            deleteGroupSetting(targetGroupId, operatorId);
        } catch (BusinessException e) {
            // 忽略不存在的错误
        }
        
        // 创建新设置
        ChatGroupSetting newSetting = createDefaultSettingEntity(targetGroupId, operatorId);
        updateSettingFromDTO(newSetting, dto);
        save(newSetting);
        
        log.info("复制群组设置成功，源群组: {}, 目标群组: {}, 操作人: {}", 
                sourceGroupId, targetGroupId, operatorId);
        
        return true;
    }

    @Override
    public Boolean checkSettingPermission(String groupId, String userId, String settingType) {
        // TODO: 实现权限检查逻辑
        // 这里应该检查用户在群组中的角色和权限
        return true;
    }

    @Override
    public List<ChatGroupSettingVO> getSettingHistory(String groupId, Integer pageNum, Integer pageSize) {
        // TODO: 实现设置历史查询
        // 这里应该查询设置变更历史记录
        return List.of();
    }

    @Override
    public String exportGroupSettings(String groupId, String operatorId) {
        // TODO: 实现设置导出
        return "";
    }

    @Override
    public Boolean importGroupSettings(String groupId, String filePath, String operatorId) {
        // TODO: 实现设置导入
        return false;
    }

    /**
     * 创建默认设置实体
     */
    private ChatGroupSetting createDefaultSettingEntity(String groupId, String creatorId) {
        ChatGroupSetting setting = new ChatGroupSetting();
        setting.setGroupId(groupId);
        setting.setJoinVerification(0);
        setting.setAllMuted(0);
        setting.setIsPublic(0);
        setting.setAllowMemberInvite(1);
        setting.setMaxMembers(100);
        setting.setMessageRetentionDays(30);
        setting.setCreateTime(LocalDateTime.now());
        setting.setUpdateTime(LocalDateTime.now());
        return setting;
    }

    /**
     * 转换为VO
     */
    private ChatGroupSettingVO convertToVO(ChatGroupSetting setting) {
        ChatGroupSettingVO vo = new ChatGroupSettingVO();
        vo.setId(setting.getId());
        vo.setGroupId(setting.getGroupId());
        vo.setJoinVerification(integerToBoolean(setting.getJoinVerification()));
        vo.setAllMuted(integerToBoolean(setting.getAllMuted()));
        vo.setIsPublic(integerToBoolean(setting.getIsPublic()));
        vo.setAllowMemberInvite(integerToBoolean(setting.getAllowMemberInvite()));
        vo.setMaxMembers(setting.getMaxMembers());
        vo.setMessageRetentionDays(setting.getMessageRetentionDays());
        vo.setCreateTime(setting.getCreateTime());
        vo.setUpdateTime(setting.getUpdateTime());
        return vo;
    }

    /**
     * 从DTO更新设置
     */
    private void updateSettingFromDTO(ChatGroupSetting setting, ChatGroupSettingDTO dto) {
        if (dto.hasGroupNameUpdate()) {
            // setting.setGroupName(dto.getGroupName());
        }
        if (dto.hasDescriptionUpdate()) {
            // setting.setDescription(dto.getDescription());
        }
        if (dto.hasAvatarUpdate()) {
            // setting.setAvatar(dto.getAvatar());
        }
        if (dto.hasNoticeUpdate()) {
            // setting.setNotice(dto.getNotice());
        }
        if (dto.getJoinVerification() != null) {
            setting.setJoinVerification(booleanToInteger(dto.getJoinVerification()));
        }
        if (dto.getAllMuted() != null) {
            setting.setAllMuted(booleanToInteger(dto.getAllMuted()));
        }
        if (dto.getIsPublic() != null) {
            setting.setIsPublic(booleanToInteger(dto.getIsPublic()));
        }
        if (dto.getAllowMemberInvite() != null) {
            setting.setAllowMemberInvite(booleanToInteger(dto.getAllowMemberInvite()));
        }
        if (dto.getMaxMembers() != null) {
            setting.setMaxMembers(dto.getMaxMembers());
        }
        if (dto.getMessageRetentionDays() != null) {
            setting.setMessageRetentionDays(dto.getMessageRetentionDays());
        }
    }

    /**
     * 复制设置到DTO
     */
    private void copySettingsToDTO(ChatGroupSettingVO source, ChatGroupSettingDTO target) {
        target.setJoinVerification(source.getJoinVerification());
        target.setAllMuted(source.getAllMuted());
        target.setIsPublic(source.getIsPublic());
        target.setAllowMemberInvite(source.getAllowMemberInvite());
        target.setMaxMembers(source.getMaxMembers());
        target.setMessageRetentionDays(source.getMessageRetentionDays());
    }

    /**
     * 更新单个字段
     */
    private Boolean updateSingleField(String groupId, String fieldName, Object value, String operatorId) {
        if (groupId == null || groupId.trim().isEmpty()) {
            throw new BusinessException("群组ID不能为空");
        }
        
        LambdaQueryWrapper<ChatGroupSetting> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatGroupSetting::getGroupId, groupId)
                   .eq(ChatGroupSetting::getIsDeleted, 0);
        
        ChatGroupSetting setting = getOne(queryWrapper);
        if (setting == null) {
            throw new BusinessException("群组设置不存在");
        }
        
        // 根据字段名设置值（这里简化处理，实际应该使用反射或其他方式）
        setting.setUpdateTime(LocalDateTime.now());
        
        boolean result = updateById(setting);
        
        if (result) {
            log.info("更新群组设置字段成功，群组ID: {}, 字段: {}, 操作人: {}", 
                    groupId, fieldName, operatorId);
        }

        return result;
    }

    /**
     * Integer转Boolean工具方法
     */
    private Boolean integerToBoolean(Integer value) {
        if (value == null) {
            return false;
        }
        return value == 1;
    }

    /**
     * Boolean转Integer工具方法
     */
    private Integer booleanToInteger(Boolean value) {
        if (value == null) {
            return 0;
        }
        return value ? 1 : 0;
    }
}
